#include "io_base.h"
#include "def.h"

static int echo_serv_thr(void)
{
	io_base_conf_t conf;
	io_base_t *base;

	snprintf(conf.name, sizeof(conf.name), "tcp_echo_serv");
	snprintf(conf.ip, sizeof(conf.ip), "127.0.0.1");
	conf.port = 8888;
	conf.mask = NULL;

	base = io_base_new(&conf);
	assert(base);

	int ret = -1;
	int timeout = -1;
	io_event_t *ev;
	io_event_iterator_t it;
	io_client_t *cli = NULL;
	sock_t sock;
	while (1) {
		ret = io_base_loop(base, timeout);
		if (ret < 0) {
			ERR("io_base_loop fail");
			break;
		}

		if (ret == 0) {
			DBG("timeout");
			continue;
		}

		io_event_iterator_init(base, &it);
		while ((ev = io_events_next(&it))) {
			if (ev->event & IO_EVENT_ERROR) {
				DBG("err event");
				io_client_put(ev->ctx);	
				continue;
			}

			if (ev->event & IO_EVENT_CLOSE) {
				DBG("close event");
				io_client_put(ev->ctx);
				continue;
			}

			if (ev->event & IO_EVENT_ACCEPT) {
				DBG("accept event");
				if (io_base_accept(base, &sock) < 0) {
					ERR("io_base_accept fail");
					break;
				}

				cli = (io_client_t *)MALLOC(sizeof(io_client_t));
				if (!cli) {
					ERR("malloc fail");
					break;
				}

				if (io_client_init(cli, &sock, base) < 0) {
					ERR("io_client_init fail");
					safe_free(cli);
					break;
				}
			}

			if (ev->event & IO_EVENT_READ) {
				DBG("read event");
				cli = (io_client_t *)ev->ctx;
				DBG("recv %u bytes: %s\n", cli->in_len, cli->in_buf);
				if (io_client_write(cli, cli->in_buf, cli->in_len) < 0) {
					ERR("io_client_write fail");
					io_client_put(cli);
				}
			}

			if (ev->event & IO_EVENT_WRITE) {
				DBG("write complete event");
				cli = (io_client_t *)ev->ctx;
				io_client_write(cli, NULL, 0);
			}
		}

	}

	io_base_destroy(&base);
	return 0;
}

int main(void)
{
	printf("** tcp_echo_test:");
	echo_serv_thr();
	printf("** tcp_echo_test success!");
	return 0;
}
